from typing import Tuple
from collections import Counter
from osgeo import gdal
from osgeo import ogr
from osgeo import osr
import pandas as pd
import numpy as np
import os


class RasterAlignment(object):
    def __init__(self, originrasterurl: str, alignmentrasterurl: list, vectorurl: list = list(),
                 vectorlabel: list = list()) -> None:
        '''

        :param originrasterurl: 基准栅格文件路径(tif)，所有其他的的矢量文件和栅格文件将以基准栅格的坐标系和数据为基准，必须存在且不为多波段栅格
        :param alignmentrasterurl: 其他栅格文件(tif)，可以为多波段栅格，以列表形式给出栅格文件路径，可以不存在
        :param vectorurl: 矢量文件路径(shp)，以列表形式给出路径，可以不存在
        :param vectorlabel: 矢量文件对齐到栅格形成表时所被标记为的值(int)1、2、3、.....，当多个矢量文件的要素在空间上重叠时，靠后的矢量文件所对应的标记有更高的优先权，
        当矢量文件路径不存在时，标签也应该不存在
        '''
        self.originrasterurl = originrasterurl
        self.alignmentrasterurl = alignmentrasterurl
        self.originrasterdataset = None
        self.alignmentrasterdatasets: list = list()
        self.coortransformX: list = list()
        self.coortransformY: list = list()
        self.originrasterspatial: osr.SpatialReference = None
        self.originrastervalueX=list()
        self.originrastervalueY=list()
        self.alignmentrasterbandcount=list()
        self.originrastervalueYrepeatcount=None
        self.originrastervalueXrepeatcount=None
        self.alignmentrasterspatials: list = list()
        self.coortransforminformation = list()
        self.originrasterwidth: int = None
        self.originrasterheight: int = None
        self.alignmentrasterwidth: list = list()
        self.alignmentrasterheight: list = list()
        self.alignmentrasterindextooriginX = list()
        self.alignmentrasterindextooriginY = list()
        self.vectorurl = vectorurl
        self.vectorlabel = vectorlabel
        self.vectortype=list()
        self.vectordatasets = list()
        self.vectorTorasterspatials: list = list()
        self.vectorcoortransforminformation: list = list()
        self.vectortotable = list()
        self.vectortooriginrasterfigurecoor = list()
        # self.rastertotablenodatavalueforword = list()
        # self.rastertotablelastvalue = list()
        self.originrastervaluecount:int=0
        self.table: pd.DataFrame = pd.DataFrame()
        pass
    def start(self):
        self.Openvector()
        self.Openraster()
        self.coortransformlist()
        self.vectortorastercoortrans()
        self.getwidthheight()
        # self.indextoindex()
        self.originrastertableindexattritube()
        self.Countlistrepeat()
        self.vectortorastercoortrans()
    def MergeRaster(self):
        self.alignmentrastertotable()
    def MergeVector(self):
        if len(self.vectortooriginrasterfigurecoor)==0:
            self.vectortofigurecoor()
        self.alignmentvectortotable()
    def FeatureMeanExport(self,index:int,mean:bool=False,url:str=None):
        if len(self.vectortooriginrasterfigurecoor)==0:
            self.vectortofigurecoor()
        self.vectortabletoout(index,mean,url)
        pass
    def Openvector(self):
        for i in range(len(self.vectorurl)):
            self.vectordatasets.append(ogr.Open(self.vectorurl[i]))
        pass

    def vectortorastercoortrans(self):
        for i in range(len(self.vectorurl)):
            layer=self.vectordatasets[i].GetLayer(0)
            vectorspatial = layer.GetSpatialRef()
            if (not(vectorspatial.IsGeographic() or vectorspatial.IsProjected())):
                raise Exception("vector {} not spatialref".format(i))
            self.vectorcoortransforminformation.append(
                osr.CoordinateTransformation(vectorspatial, self.originrasterspatial))
        pass

    def Openraster(self) -> None:
        self.originrasterdataset = gdal.Open(self.originrasterurl)
        for i in range(len(self.alignmentrasterurl)):
            self.alignmentrasterdatasets.append(gdal.Open(self.alignmentrasterurl[i]))
        for i in self.alignmentrasterdatasets:
            self.alignmentrasterbandcount.append(i.RasterCount)
        pass
    def coortransformlist(self) -> None:
        self.originrasterspatial = osr.SpatialReference()
        self.originrasterspatial.ImportFromWkt(self.originrasterdataset.GetProjectionRef())
        if not(self.originrasterspatial.IsGeographic() or self.originrasterspatial.IsProjected()):
            raise Exception("originraster is not spatialreference")
        for i in range(len(self.alignmentrasterurl)):
            alignmentrasterspatial = osr.SpatialReference()
            alignmentrasterspatial.ImportFromWkt(self.alignmentrasterdatasets[i].GetProjectionRef())
            if not(alignmentrasterspatial.IsGeographic() or alignmentrasterspatial.IsProjected()):
                raise Exception("alignmentraster {0} is not spatialreference".format(i + 1))
            if (alignmentrasterspatial == self.originrasterspatial):
                self.alignmentrasterspatials.append(None)
            else:
                self.alignmentrasterspatials.append(alignmentrasterspatial)
        for i in range(len(self.alignmentrasterurl)):
            if self.alignmentrasterspatials[i] == None:
                self.coortransforminformation.append(None)
            else:
                self.coortransforminformation.append(
                    osr.CoordinateTransformation(self.originrasterspatial, self.alignmentrasterspatials[i]))
        # for i in range(len(self.alignmentrasterurl)):
        #     originrastergeoifo = self.originrasterdataset.GetGeoTransform()
        #     alignmentrasterifo = self.alignmentrasterdatasets[i].GetGeoTransform()
        #     # self.coortransformX.append(self.zoomfactor(originrastergeoifo[0],originrastergeoifo[1],
        #     #                                             alignmentrasterifo[0],alignmentrasterifo[1],self.coortransforminformation[i]))
        #     # self.coortransformY.append(self.zoomfactor(originrastergeoifo[3],originrastergeoifo[5],
        #     #                                             alignmentrasterifo[3],alignmentrasterifo[5],self.coortransforminformation[i]))
        #     zoomX, zoomY = self.zoomfactor(originrastergeoifo[0], originrastergeoifo[1], originrastergeoifo[3],
        #                                    originrastergeoifo[5],
        #                                    alignmentrasterifo[0], alignmentrasterifo[1], alignmentrasterifo[3],
        #                                    alignmentrasterifo[5], self.coortransforminformation[i])
        #     self.coortransformX.append(zoomX)
        #     self.coortransformY.append(zoomY)

        pass

    def zoomfactor(self, sourceX: float, sourceW: float, sourceY: float, sourceH: float,
                   targetX: float, targetW: float, targetY: float, targetH: float, transforminformation) -> Tuple[Tuple[float, float], Tuple[float, float]]:
        zoomfactorvalue = None
        if (transforminformation == None):
            zoomX1 = (sourceX + sourceW * 0.5 - targetX - targetW * 0.5) / targetW
            zoomX2 = sourceW / targetW
            zoomY1 = (sourceY + sourceH * 0.5 - targetY - targetH * 0.5) / targetH
            zoomY2 = sourceH / targetH
            zoomfactorvalue = ((zoomX1, zoomX2), (zoomY1, zoomY2))
        else:
            transX, transY, Z = transforminformation.TransformPoint(sourceX, sourceY)

            transW, transH, Z = transforminformation.TransformPoint(sourceX+sourceW, sourceY+sourceH)
            transW = transW - transX
            transH = transH - transY
            zoomX1 = (transX + transW * 0.5 - targetX - targetW * 0.5) / targetW
            zoomX2 = transW / targetW
            zoomY1 = (transY + transH * 0.5 - targetY - targetH * 0.5) / targetH
            zoomY2 = transH / targetH
            zoomfactorvalue = ((zoomX1, zoomX2), (zoomY1, zoomY2))
        return zoomfactorvalue

    def getwidthheight(self):
        self.originrasterwidth = self.originrasterdataset.RasterXSize
        self.originrasterheight = self.originrasterdataset.RasterYSize
        for i in range(len(self.alignmentrasterurl)):
            self.alignmentrasterwidth.append(self.alignmentrasterdatasets[i].RasterXSize)
            self.alignmentrasterheight.append(self.alignmentrasterdatasets[i].RasterYSize)
        pass

    def indexzoom(self, coor: float) -> int:
        X = coor // 1
        if (coor % 1 >= 0.5):
            X = X + 1
        else:
            pass
        return int(X)

    def indextoindex(self) -> None:
        # indexx=X*self.coortransformX[i][2]+self.coortransformX[i][0]
        # indexy=Y*self.coortransformY[i][2]+self.coortransformY[i][0]
        temporary = list()
        originrastergeoifo = self.originrasterdataset.GetGeoTransform()
        for i in range(len(self.alignmentrasterurl)):
            alignmentrasterifo = self.alignmentrasterdatasets[i].GetGeoTransform()
            for j in range(self.originrasterwidth):
                # indexx = j * self.coortransformX[i][1] + self.coortransformX[i][0]
                # indexx = self.indexzoom(indexx)

                X,Y,Z=self.coortransforminformation[i].TransformPoint(originrastergeoifo[0]+(j)*originrastergeoifo[1],
                                                                      originrastergeoifo[3]+(0)*originrastergeoifo[5])
                X=(X-alignmentrasterifo[0])/alignmentrasterifo[1]
                indexx=self.indexzoom(X)

                if (indexx >= self.alignmentrasterwidth[i]):
                    temporary.append(None)
                else:
                    temporary.append(indexx)
            self.alignmentrasterindextooriginX.append(temporary.copy())
            temporary.clear()
            for j in range(self.originrasterheight):
                # indexy = j * self.coortransformY[i][1] + self.coortransformY[i][0]
                # indexy = self.indexzoom(indexy)
                X, Y, Z = self.coortransforminformation[i].TransformPoint(
                    originrastergeoifo[0] + (0)*originrastergeoifo[1],
                    originrastergeoifo[3] + (j) * originrastergeoifo[5])
                Y = (Y - alignmentrasterifo[3]) / alignmentrasterifo[5]
                indexy = self.indexzoom(Y)
                if (indexy >= self.alignmentrasterheight[i]):
                    temporary.append(None)
                else:
                    temporary.append(indexy)
            self.alignmentrasterindextooriginY.append(temporary.copy())
            temporary.clear()
        pass

    def recttopoint(self, min_x, max_x, min_y, max_y, polygonpointX, polygonpointY, originrastergeoifo) -> list:
        temporary = list()
        for i in range(min_x, max_x + 1, 1):
            for j in range(max_y, min_y + 1, 1):
                if (self.is_point_inside_polygon((i + 0.5) * originrastergeoifo[1] + originrastergeoifo[0],
                    (j + 0.5) * originrastergeoifo[3] + originrastergeoifo[5], polygonpointX, polygonpointY)):
                    temporary.append((i, j))
        temporary.append(None)
        return temporary

    def polygontofigurecoor(self, index: int,transform):
        temporary = list()
        originrastergeoifo = self.originrasterdataset.GetGeoTransform()
        layer = self.vectordatasets[index].GetLayer(0)
        layer.ResetReading()
        feature = layer.GetNextFeature()
        polygonpointX = list()
        polygonpointY = list()
        while feature:
            arc = feature.GetGeometryRef()
            # 左下x、y和右上x、y
            min_x, max_x, min_y, max_y = arc.GetEnvelope()
            transform.TransformPoint(1.1, 1.1,0)
            min_x, min_y, min_z = transform.TransformPoint(min_x, min_y)
            min_x = int((min_x - originrastergeoifo[0]) / originrastergeoifo[1])
            min_y = int((min_y - originrastergeoifo[3]) / originrastergeoifo[5])
            max_x, max_y, max_z = transform.TransformPoint(max_x, max_y)
            max_x = int((max_x - originrastergeoifo[0]) / originrastergeoifo[1])
            max_y = int((max_y - originrastergeoifo[3]) / originrastergeoifo[5])
            min_x-=1
            min_y+=1
            max_x+=1
            max_y-=1
            if (min_x >= self.originrasterwidth): min_x = self.originrasterwidth - 1
            if (min_y >= self.originrasterheight): min_y = self.originrasterheight - 1
            if (max_x >= self.originrasterwidth): max_x = self.originrasterwidth - 1
            if (max_y >= self.originrasterheight): max_y = self.originrasterheight - 1
            for i in range(arc.GetGeometryCount()):
                arc0 = arc.GetGeometryRef(i)
                for j in range(arc0.GetPointCount()):
                    X, Y, Z = transform.TransformPoint(arc0.GetX(j), arc0.GetY(j))
                    # X=int((X-originrastergeoifo[0])/originrastergeoifo[1])
                    # Y=int((Y-originrastergeoifo[3])/originrastergeoifo[5])
                    polygonpointX.append(X)
                    polygonpointY.append(Y)
            temporary+=self.recttopoint(min_x, max_x, min_y, max_y, polygonpointX, polygonpointY, originrastergeoifo)
            polygonpointX.clear()
            polygonpointY.clear()
            feature = layer.GetNextFeature()
        self.vectortooriginrasterfigurecoor.append(temporary)

    def pointtofigurecoor(self, index: int,transform):
        originrastergeoifo = self.originrasterdataset.GetGeoTransform()
        temporary = list()
        layer = self.vectordatasets[index].GetLayer(0)
        layer.ResetReading()
        feature = layer.GetNextFeature()
        while feature:
            arc = feature.GetGeometryRef()
            X, Y, Z = transform.TransformPoint(arc.GetX(), arc.GetY())
            X = int((X - originrastergeoifo[0]) / originrastergeoifo[1])
            Y = int((Y - originrastergeoifo[3]) / originrastergeoifo[5])
            if (X >= self.originrasterwidth or Y >= self.originrasterheight):
                temporary.append(None)
            else:
                temporary.append((X, Y))
                temporary.append(None)
            feature = layer.GetNextFeature()
        self.vectortooriginrasterfigurecoor.append(temporary)

    def is_point_inside_polygon(self, x, y, x_coords, y_coords) -> bool:
        num_vertices = len(x_coords)
        i = 0
        j = num_vertices - 1
        inside = False

        for i in range(num_vertices):
            j = (i + 1) % num_vertices
            # 如果点在多边形的边上，直接返回True
            if (x_coords[i] <= x < x_coords[j] or x_coords[j] <= x < x_coords[i]) and (y_coords[j] < y != y_coords[i]):
                return True

                # 检查射线与多边形边的交点
            if (y_coords[i] < y and y <= y_coords[j]) or (y_coords[j] < y and y <= y_coords[i]):
                xinters = (y - y_coords[i]) * (x_coords[j] - x_coords[i]) / (y_coords[j] - y_coords[i]) + x_coords[i]
                if x_coords[i] < xinters < x_coords[j] or x_coords[j] < xinters < x_coords[i]:
                    inside = not inside

        return inside

    def vectortofigurecoor(self):
        for i in range(len(self.vectorurl)):
            layer = self.vectordatasets[i].GetLayer(0)
            feature = layer.GetFeature(0)
            ref=feature.GetGeometryRef()
            if ref.GetGeometryName() == "POLYGON":
                self.vectortype.append("POLYGON")
                self.polygontofigurecoor(i,self.vectorcoortransforminformation[i])
            elif ref.GetGeometryName() == "POINT":
                self.vectortype.append("POINT")
                self.pointtofigurecoor(i,self.vectorcoortransforminformation[i])
            else:
                raise Exception("vector {0} is not POLYGON or POINT".format(i))

    def alignmentvectortotable(self):
        originrasterband=self.originrasterdataset.GetRasterBand(1)
        originrasterdata=originrasterband.ReadAsArray()
        nodatavalue=originrasterdata[0][0]
        temporary = [0 for i in range(self.originrastervaluecount)]
        for i in range(len(self.vectorurl)):
            for j in range(len(self.vectortooriginrasterfigurecoor[i])):
                if (self.vectortooriginrasterfigurecoor[i][j] == None):
                    pass
                else:
                    X, Y = self.vectortooriginrasterfigurecoor[i][j]
                    if (originrasterdata[Y][X]==nodatavalue):
                        pass
                    else:
                        index=self.figureindextotableindex(X,Y)
                        if(index==-1):
                            raise Exception("no index")
                        temporary[index] = self.vectorlabel[i]
        self.table[os.path.splitext(os.path.basename(self.vectorurl[0]))[0]] = temporary
        #temporary.clear()
        pass

    def Countlistrepeat(self):
        self.originrastervalueYrepeatcount=list(Counter(self.originrastervalueY).items())
        self.originrastervalueXrepeatcount=list(Counter(self.originrastervalueX).items())
        pass

    def figureindextotableindex(self,X,Y)->int:
        index=0
        for i,count in self.originrastervalueYrepeatcount:
            if(Y==i):
                break
            else:
                index+=count
        indexcopy=index
        for i in range(self.originrasterwidth):
            if(self.originrastervalueX[i+indexcopy]==X):
                return int(index)
            else:
                index+=1
        return -1

    def vectortabletoout(self, vectorindex:int,mean:bool=False, url:str=None):
        if url==None:
            return
        if self.table.empty:
            return
        if mean==False:
            return
        temporary = list()
        originrasterband = self.originrasterdataset.GetRasterBand(1)
        originrasterdata = originrasterband.ReadAsArray()
        nodatavalue = originrasterdata[0][0]
        colmusname=list()
        colmusname.append(os.path.splitext(os.path.basename(self.originrasterurl))[0])
        bandcount=0
        for i,item in enumerate(self.alignmentrasterbandcount):
            bandcount+=item
            if item==1:
                colmusname.append(os.path.splitext(os.path.basename(self.alignmentrasterurl[i]))[0])
            else:
                for j in range(item):
                    colmusname.append(os.path.splitext(os.path.basename(self.alignmentrasterurl[i]))[0]+"-"+str(j+1))
        layer=self.vectordatasets[vectorindex].GetLayer(0)
        featurecount=layer.GetFeatureCount()
        outarray= np.zeros((featurecount, bandcount+1), dtype=float)
        featureindex=0
        labellist=[0 for i in range(featurecount)]
        for j in range(len(self.vectortooriginrasterfigurecoor[vectorindex])):
            if (self.vectortooriginrasterfigurecoor[vectorindex][j] == None):
                if(len(temporary)!=0):
                    select_df=self.table.iloc[temporary,:]
                    select_df=select_df.loc[:,colmusname]
                    temporaryarray=np.array(select_df)
                    outarray[featureindex]=temporaryarray.sum(axis=0)
                    labellist[featureindex]=self.vectorlabel[vectorindex]
                else:
                    pass
                temporary.clear()
                featureindex+=1
                pass
            else:
                X, Y = self.vectortooriginrasterfigurecoor[vectorindex][j]
                if (originrasterdata[Y][X] == nodatavalue):
                    pass
                else:
                    index = self.figureindextotableindex(X, Y)
                    if (index == -1):
                        raise Exception("no index")
                    temporary.append(index)
        temporarydata = pd.DataFrame(outarray)
        temporarydata.columns=colmusname
        temporarydata[os.path.splitext(os.path.basename(self.vectorurl[vectorindex]))[0]] = labellist
        temporarydata.to_csv(url, index=None)
        pass
    def alignmentrastertotable(self):
        temporary = list()
        originrastergeoifo=self.originrasterdataset.GetGeoTransform()
        for i in range(len(self.alignmentrasterurl)):
            temporary.clear()
            temporarydata = None
            Rastercount=self.alignmentrasterdatasets[i].RasterCount
            alignmentrasterifo=self.alignmentrasterdatasets[i].GetGeoTransform()
            for band in range(Rastercount):
                temporary.clear()
                temporarydata = None
                banddata=self.alignmentrasterdatasets[i].GetRasterBand(band+1)
                temporarydata = banddata.ReadAsArray()
                bandnodatavalue=banddata.GetNoDataValue()
                if(bandnodatavalue==None):
                    bandnodatavalue=temporarydata[0][0]
                #注意读取为array数组后和从gdal中取出的nodatavalue不同
                bandnodatavalue = temporarydata[0][0]
                for j,k in zip(self.originrastervalueY,self.originrastervalueX):

                    X, Y, Z = self.coortransforminformation[i].TransformPoint(
                        originrastergeoifo[0] + (k) * originrastergeoifo[1],
                        originrastergeoifo[3] + (j) * originrastergeoifo[5])
                    X = (X - alignmentrasterifo[0]) / alignmentrasterifo[1]
                    Y = (Y - alignmentrasterifo[3]) / alignmentrasterifo[5]
                    X=self.indexzoom(X)
                    Y=self.indexzoom(Y)
                    # X = self.alignmentrasterindextooriginX[i][k]
                    # Y = self.alignmentrasterindextooriginY[i][j]
                    if(X>=self.alignmentrasterwidth[i]):
                        X=None
                    if(Y>=self.alignmentrasterheight[i]):
                        Y=None
                    if (X == None or Y == None):
                        temporary.append(None)
                    elif temporarydata[Y][X]==bandnodatavalue:
                        temporary.append(None)
                    else:
                        temporary.append(temporarydata[Y][X])
                if Rastercount==1:
                    self.table[os.path.splitext(os.path.basename(self.alignmentrasterurl[i]))[0]] = temporary
                else:
                    self.table[os.path.splitext(os.path.basename(self.alignmentrasterurl[i]))[0]+"-"+str(band+1)] = temporary
        pass
    def originrastertotable(self, originrasterdata,nodatavalue) -> None:
        # band = self.originrasterdataset.GetRasterBand(1)
        # nodatavalue = band.GetNoDataValue()
        ax, ay = np.where(originrasterdata != nodatavalue)
        self.originrastervalueX=list(ay)
        self.originrastervalueY=list(ax)
        self.originrastervaluecount=len(ax)
        self.table = pd.DataFrame({"index": [i for i in range(self.originrastervaluecount)],
                                   os.path.splitext(os.path.basename(self.originrasterurl))[0]: list(originrasterdata[ax,ay])})
        pass
    def originrastertableindexattritube(self) -> None:
        band = self.originrasterdataset.GetRasterBand(1)
        nodatavalue = band.GetNoDataValue()
        origindata = band.ReadAsArray()
        if (nodatavalue == None):
            nodatavalue=origindata[0][0]
        #读取数据后array中数据和nodatavalue不同！！！！
        nodatavalue = origindata[0][0]
        self.originrastertotable(origindata,nodatavalue)
        origindata = None
        pass

    def saveascsv(self, url):
        if not(self.table.empty):
            self.table.to_csv(url, index=None)

    def saveasexcel(self, url):
        if not(self.table.empty):
            self.table.to_excel(url, index=None)
    def to_tif(self,data:np.ndarray,NodataValue,url:str,stdref:str='')->None:
        '''
        :param data: 要转成栅格的数据，期望是一维数组
        :param NodataValue: 期望是int或float类型
        :param url: 栅格保存的路径
        :param stdref: 基准栅格路径，如果不存在，以构造对象时传入的基准栅格为基准
        :return: None
        '''
        if len(url)==0:
            raise Exception("文件路径错误")
        if len(stdref)==0:
            if data.size != self.originrastervaluecount:
                raise Exception("基准栅格数据和要转成栅格的数据不匹配")
            else:
                band = self.originrasterdataset.GetRasterBand(1)
                oridata = band.ReadAsArray()
                ax, ay = np.where(oridata != oridata[0][0])
                oridata[ax,ay]=data
                ax, ay = np.where(oridata == oridata[0][0])
                oridata[ax,ay]=NodataValue
                trans = self.originrasterdataset.GetGeoTransform()
                wgs = self.originrasterdataset.GetProjection()
                self.save_tif(oridata, trans, wgs, NodataValue, url)

        else:
            dataset=gdal.Open(stdref)
            band=dataset.GetRasterBand(1)
            oridata=band.ReadAsArray()
            ax,ay=np.where(oridata!=oridata[0][0])
            if len(ax)!=data.size:
                # 可以选择不减少引用计数，函数结束，引用计数--，局部变量自动销毁
                dataset=None
                raise Exception("基准栅格数据和要转成栅格的数据不匹配")
            oridata[ax, ay] = data
            ax, ay = np.where(oridata == oridata[0][0])
            oridata[ax, ay] = NodataValue
            trans = dataset.GetGeoTransform()
            wgs = dataset.GetProjection()
            self.save_tif(oridata, trans, wgs, NodataValue, url)
        pass
    def save_tif(self,data,trans,wgs,NodataValue,url:str):
        # 数组shape
        row = data.shape[0]  # 行数
        columns = data.shape[1]  # 列数
        dim = 1  # 通道数

        # 创建驱动
        driver = gdal.GetDriverByName('GTiff')
        # 创建文件
        dst_ds = driver.Create(url, columns, row, dim, gdal.GDT_Float32)
        # 设置几何信息
        dst_ds.SetGeoTransform(trans)
        dst_ds.SetProjection(wgs)

        # 将数组写入
        dst_ds.GetRasterBand(1).WriteArray(data)
        dst_ds.GetRasterBand(1).SetNoDataValue(NodataValue)

        # 写入硬盘
        dst_ds.FlushCache()
        dst_ds = None
        pass
    def __del__(self):
        for i in range(len(self.alignmentrasterurl)):
            self.alignmentrasterdatasets[i] = None
        self.originrasterdataset = None
        for i in range(len(self.vectordatasets)):
            self.vectordatasets[i] = None
        self.table = None